<script lang="ts">
	export let data;
	import { knowledge1, storageFiles } from "$lib/shared/stores/common/Store";
	import { onMount, onDestroy } from "svelte";
	import {
		LOCAL_STORAGE_KEY,
		MessageRole,
		MessageType,
		type Message,
	} from "$lib/shared/constant/Interface";
	import {
		getCurrentTimeStamp,
		scrollToBottom,
		scrollToTop,
	} from "$lib/shared/Utils";
	import { fetchTextStream } from "$lib/network/chat/Network"; // 引入后端交互函数
	import MessageInput from "$lib/modules/chat/MessageInput.svelte";
	import ChatMessage from "$lib/modules/chat/ChatMessage.svelte";
	import { fetchAllFile } from "$lib/network/upload/Network.js";
	import { getNotificationsContext } from "svelte-notifications";
	import { goto } from "$app/navigation";
	import { sendMessageToBackend } from "$lib/network/chat/Network";
	let query: string = "";
	let finalQuery: string = "";
	let appendix_query: string = ""; // 新增变量用于存储附加内容
	let validMessage: string = "";
	let loading = false; // 控制加载状态
	let scrollToDiv: HTMLDivElement; // 聊天框滚动元素
	let chatMessages: Message[] = data.chatMsg ? data.chatMsg : [];
	const { addNotification } = getNotificationsContext(); // 获取通知上下文
	$: knowledge_1 = $knowledge1?.id ? $knowledge1.id : "default";
	const STORAGE_CHAT_KEY_DRAWER = "DRAWER";
	// 页面加载时获取文件
	onMount(async () => {
		// sessionStorage.setItem("msg_key", accmulatedMsg);
		scrollToDiv = document
			.querySelector(".chat-scrollbar")
			?.querySelector(".svlr-viewport")!;

		const res = await fetchAllFile();
		if (res) {
			storageFiles.set(res);
		}
		// 读取 localStorage 的聊天记录
		const storedMessages = sessionStorage.getItem(STORAGE_CHAT_KEY_DRAWER);
		console.log(
			"storedMessages",
			storedMessages,
			"time",
			sessionStorage.getItem(STORAGE_CHAT_KEY_DRAWER)
		);
		if (storedMessages) {
			chatMessages = JSON.parse(storedMessages);
		}

		// 监听 beforeunload 事件，确保聊天记录存储
		const handleBeforeUnload = () => {
			storeMessages();
		};

		window.addEventListener("beforeunload", handleBeforeUnload);

		// 添加图片上传事件监听器
		const handleImageUpload = (event: CustomEvent) => {
			appendix_query = event.detail.imageText;
		};

		window.addEventListener(
			"imageUploaded",
			handleImageUpload as EventListener
		);

		// 清理事件监听器
		return () => {
			sessionStorage.removeItem(STORAGE_CHAT_KEY_DRAWER);
			window.removeEventListener(
				"imageUploaded",
				handleImageUpload as EventListener
			);
		};
	});

	// 显示通知
	function showNotification(text: string, type: string) {
		addNotification({
			text: text,
			position: "top-left",
			type: type,
			removeAfter: 3000,
		});
	}

	function handleTop() {
		scrollToTop(scrollToDiv);
	}

	function storeMessages() {
		// 将聊天记录存储在 sessionStorage 中
		sessionStorage.setItem(
			STORAGE_CHAT_KEY_DRAWER,
			JSON.stringify(chatMessages)
		);
	}

	function decodeEscapedBytes(str: string): string {
		const byteArray = str
			.split("\\x")
			.slice(1)
			.map((byte) => parseInt(byte, 16));
		const decoded = new TextDecoder("utf-8").decode(new Uint8Array(byteArray));

		return decoded;
	}

	function decodeUnicode(str: string): string {
		const decoded = str.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
			return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
		});

		return decoded;
	}

	// 处理发送消息
	const handleTextSubmit = async () => {
		if (!query) return; // 防止空消息提交

		loading = true;

		// 清空之前的累积消息
		sessionStorage.removeItem("msg_key");

		// 如果有附加查询，将其添加到 finalQuery
		const completeQuery = appendix_query ? `${query} ${appendix_query}` : query;

		const newMessage = {
			role: MessageRole.User,
			type: MessageType.Text,
			content: completeQuery,
			time: 0,
		};
		chatMessages = [...chatMessages, newMessage];
		scrollToBottom(scrollToDiv);
		storeMessages();
		query = "";
		appendix_query = ""; // 重置附加查询

		console.log("finalQuery", completeQuery);
		await callTextStream(completeQuery, getCurrentTimeStamp());
		scrollToBottom(scrollToDiv);
		storeMessages();
	};
	const extractMessage = (rawMessage: string): string => {
		// 移除 'b'' 和空字符串的部分
		let cleanedMessage = rawMessage.replace(/b''/g, ""); // 删除空的 b''

		// 提取出 b'...b' 之间的内容
		cleanedMessage = cleanedMessage.replace(/b'(.*?)'/g, "$1"); // 匹配 b'...' 并提取出内容

		cleanedMessage = cleanedMessage.replace(/\[DONE\]/g, ""); // 删除 [DONE] 标记

		return cleanedMessage;
	};
	// 通过流式接口获取聊天内容
	const callTextStream = async (query: string, startSendTime: number) => {
		try {
			const eventSource = await fetchTextStream(query);
			eventSource.addEventListener("error", (e: any) => {
				if (e.type === "error") {
					showNotification("Failed to load chat content.", "error");
					loading = false;
				}
			});

			eventSource.addEventListener("message", (e: any) => {
				let msg = e.data;
				console.log("msg", msg);

				// Accumulate messages in sessionStorage
				let accumulatedMsg = sessionStorage.getItem("msg_key") || ""; // Get existing messages or start with an empty string
				accumulatedMsg += msg; // Append the new message
				sessionStorage.setItem("msg_key", accumulatedMsg); // Save the accumulated content
				console.log("acc", accumulatedMsg);
				const handleDecodedMessage = (decodedMsg: string) => {
					if (decodedMsg !== "</s>") {
						decodedMsg = decodedMsg.replace(/\\n/g, "\n");
					}

					if (chatMessages[chatMessages.length - 1].role === MessageRole.User) {
						chatMessages.push({
							role: MessageRole.Assistant,
							type: MessageType.Text,
							content: decodedMsg,
							time: startSendTime,
						});
					} else {
						chatMessages[chatMessages.length - 1].content += decodedMsg;
					}

					scrollToBottom(scrollToDiv);
				};

				if (msg.startsWith("b")) {
					let currentMsg = msg.slice(2, -1);

					if (/\\x[\dA-Fa-f]{2}/.test(currentMsg)) {
						currentMsg = decodeEscapedBytes(currentMsg);
					} else if (/\\u[\dA-Fa-f]{4}/.test(currentMsg)) {
						currentMsg = decodeUnicode(currentMsg);
					}

					handleDecodedMessage(currentMsg);
				} else if (msg === "[DONE]") {
					console.log("Done");
					let fullMessage = sessionStorage.getItem("msg_key") || "";
					console.log("Full message received:", fullMessage);
					// 提取有效信息
					validMessage = extractMessage(accumulatedMsg);
					console.log("Final extracted message: ", validMessage);
					if (validMessage) {
						sendMessageToBackend(validMessage); // 确保 validMessage 是有效的
					} else {
						console.error("No valid message extracted.");
					}

					let startTime = chatMessages[chatMessages.length - 1].time;
					loading = false;
					let totalTime = parseFloat(
						((getCurrentTimeStamp() - startTime) / 1000).toFixed(2)
					);

					if (chatMessages.length - 1 !== -1) {
						chatMessages[chatMessages.length - 1].time = totalTime;
					}

					// 清空累积消息
					sessionStorage.removeItem("msg_key");

					storeMessages();
				} else {
					if (/\\x[\dA-Fa-f]{2}/.test(msg)) {
						msg = decodeEscapedBytes(msg);
					} else if (/\\u[\dA-Fa-f]{4}/.test(msg)) {
						msg = decodeUnicode(msg);
					}

					let currentMsg = msg.replace(/"/g, "").replace(/\\n/g, "\n");

					handleDecodedMessage(currentMsg);
				}
			});
			// await sendMessageToBackend(validMessage);

			eventSource.stream();
		} catch (error: any) {
			showNotification("Failed to load chat content.", "error");
			loading = false;
		}
	};
</script>

<!-- Main layout -->
<div class="flex h-full">
	<!-- Sidebar -->
	<div class="fixed left-0 top-0 h-full w-64 bg-[#bfc4da] text-white">
		<div class="p-4">
			<h2 class="mb-6 text-2xl font-bold">Sidebar</h2>
			<ul class="space-y-4">
				<li>
					<button
						on:click={() => goto("/drawer")}
						class="w-full rounded-lg bg-[#654e72] px-4 py-2 text-left text-lg font-semibold transition-all duration-200 ease-in-out hover:bg-[#c7bdd6] focus:bg-gray-600 active:bg-[#c7bdd6]"
					>
						Go to Drawer
					</button>
				</li>
				<li>
					<button
						on:click={() => goto("/project")}
						class="w-full rounded-lg bg-[#654e72] px-4 py-2 text-left text-lg font-semibold transition-all duration-200 ease-in-out hover:bg-[#c7bdd6] focus:bg-gray-600 active:bg-[#c7bdd6]"
					>
						Go to Project
					</button>
				</li>
			</ul>
		</div>
	</div>

	<!-- Main content -->
	<div class="main-content ml-64 flex flex-1 flex-col p-4">
		<!-- Chat display area -->
		<div
			class="flex-1 overflow-auto rounded-lg border border-[#b1a9da] bg-white p-4"
		>
			<div class="flex flex-col gap-2">
				<div class="flex justify-between p-0">
					<p class="text-[1.7rem] font-bold tracking-tight text-[#6c80a9]">
						Drawer
					</p>
				</div>

				<!-- Chat messages -->
				<div class="chat-messages" style="overflow-y: auto;">
					{#each chatMessages as message, i}
						<ChatMessage on:scrollTop={() => handleTop()} msg={message} />
					{/each}
					<p>{chatMessages.length} messages in total</p>
					<!-- Loading animation -->
					{#if loading}
						<div
							style="height: 50px; display: flex; align-items: center; justify-content: center;"
						>
							<div class="spinner" />
						</div>
					{/if}
				</div>
			</div>
		</div>

		<!-- Chat input box -->
		<div class="chat-input left-64 right-0 bg-white p-2">
			<!-- <div class="flex gap-2">
				<input
					type="text"
					class="flex-1 rounded border p-2"
					bind:value={query}
					placeholder="Type your message..."
					on:keydown={handleKeydown}
				/>
				<button
					class="rounded bg-blue-500 p-2 text-white"
					on:click={() => {
						if (query) {
							handleTextSubmit();
						}
					}}
					type="submit"
					id="send"
				>
					<PaperAirplane />
				</button>
			</div> -->
			<MessageInput bind:query on:submit={(e) => handleTextSubmit()} />
		</div>
	</div>
</div>

<style>
	.spinner {
		border: 4px solid #f3f3f3; /* 背景圆圈 */
		border-top: 4px solid #705e78; /* 旋转部分的颜色 */
		border-radius: 50%;
		width: 20px;
		height: 20px;
		animation: spin 1s linear infinite;
	}

	@keyframes spin {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}

	button {
		background-color: #654e72;
		color: white;
		padding: 10px 20px;
		border: none;
		border-radius: 5px;
		cursor: pointer;
	}

	button:hover {
		background-color: #c7bdd6;
	}

	.transition-transform {
		transition: transform 0.3s ease-in-out;
	}

	.main-content {
		margin-left: 264px; /* 侧边栏宽度 + 8px的额外空间 */
		padding: 16px;
		height: 100%;
		overflow: auto;
	}

	.chat-messages {
		padding-bottom: 80px; /* 为输入框留出空间 */
	}

	.chat-input {
		z-index: 1000; /* 确保输入框在最上层 */
	}
</style>
